package com.cpsdna.module;

import com.cpsdna.bean.document.Document;
import com.cpsdna.bean.firm.Firm;
import com.cpsdna.bean.user.LoginLog;
import com.cpsdna.bean.user.User;
import com.cpsdna.util.SessionManger;
import com.cpsdna.util.Util;
import eu.bitwalker.useragentutils.UserAgent;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Criteria;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.random.R;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.filter.CheckSession;
import org.nutz.service.EntityService;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Jianghao on 2017/2/27.
 */
@IocBean(fields = {"dao"})
@Ok("json:{locked:'password|salt', ignoreNull:true}")
@Fail("http:500")
public class ControlModule extends EntityService<User> {

    private static final Log log = Logs.get();

    @GET
    @At("/login")
    @Ok("beetl:/login.btl")
    public Map<String, Object> login() throws IOException {

        if (SessionManger.checkLogin(Mvcs.getReq()))
            Mvcs.getResp().sendRedirect("/index.htm");
        Map<String, Object> map = new HashMap<String, Object>();
        String returnUrl = Mvcs.getReq().getParameter("returnUrl");
        if (!Strings.isBlank(returnUrl))
            map.put("returnUrl", returnUrl);
        return map;
    }

    @GET
    @At("/register")
    @Ok("beetl:/register.btl")
    public Map<String, Object> register() throws IOException {

        if (SessionManger.checkLogin(Mvcs.getReq()))
            Mvcs.getResp().sendRedirect("/index.htm");
        Map<String, Object> map = new HashMap<String, Object>();
        return map;
    }

    @At("/logout")
    @Ok("redirect:/login.htm")
    public void logout() throws IOException {
        Mvcs.getReq().getSession().invalidate();
    }

    @POST
    @At("/register")
    @Ok("redirect:${obj}")
    public String register(@Param("mobile") String mobile,
                           @Param("password") String password) {

        if (Strings.isNotBlank(mobile) && Strings.isMobile(mobile) && Strings.isNotBlank(password)) {

            try {

                User user = new User();
                user.setAccountStatus(0);
                user.setAvatarUrl("");
                user.setFirmId(0);
                user.setMobile(mobile);
                user.setEmail(Util.phone2Email(mobile));
                user.setRegistrationIP(Lang.getIP(Mvcs.getReq()));
                user.setSalt(R.UU32());
                user.setNickName("");
                user.setUserGroup("{0}");
                user.setRegistrationTime(Times.now());
                user.setPassword(Lang.md5(Lang.md5(password) + user.getSalt()));
                dao().insert(user);

//                UserAgent userAgent = UserAgent.parseUserAgentString(Mvcs.getReq().getHeader("User-Agent"));
//                dao().fastInsert(new LoginLog(user.getUserId(), "操作系统版本（" + userAgent.getOperatingSystem() +
//                        "）；浏览器版本（" + userAgent.getBrowser() + " - " + userAgent.getBrowserVersion() + "）", Lang
//                        .getIP(Mvcs.getReq()), Times.now()));
//                Mvcs.getReq().getSession().setAttribute(User.USER_SESSION_KEY, user);
                return "/login.htm";
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return "/register.htm";
            }
        }
        return "/register.htm";
    }

    @POST
    @At("/login")
    @Ok("redirect:${obj}")
    public String login(@Param("mobile") String mobile,
                        @Param("password") String password) {

        String returnUrl = Mvcs.getReq().getParameter("returnUrl");

        if (!Lang.isEmpty(mobile) && !Lang.isEmpty(password)) {
            User user = dao().fetch(User.class, Cnd.wrap("mobile = '" + Sqls.escapeFieldValue(mobile.trim()) + "' " +
                    "and password = md5(concat(md5('" + Sqls.escapeFieldValue(password)
                    + "'), salt))"));
            if (user != null) {

                user.setSalt(R.UU32());
                user.setPassword(Lang.md5(Lang.md5(password) + user.getSalt()));
                dao().update(user, "^(password|salt)$");
                dao().fetchLinks(user, "firm");
                UserAgent userAgent = UserAgent.parseUserAgentString(Mvcs.getReq().getHeader("User-Agent"));
                dao().fastInsert(new LoginLog(user.getUserId(), "操作系统版本（" + userAgent.getOperatingSystem() +
                        "）；浏览器版本（" + userAgent.getBrowser() + " - " + userAgent.getBrowserVersion() + "）", Lang
                        .getIP(Mvcs.getReq()), Times.now()));
                Mvcs.getReq().getSession().setAttribute(User.USER_SESSION_KEY, user);
                if (!Lang.isEmpty(returnUrl))
                    return returnUrl;
                else
                    return "/index.htm";
            } else
                return "/login.htm";
        } else
            return "/login.htm";
    }

    @GET
    @At("/index")
    @Ok("beetl:/index.btl")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/index.htm"}))
    public Map<String, Object> index() throws IOException {

        Map<String, Object> map = new HashMap<String, Object>();
        User user = SessionManger.getCurrentUser(Mvcs.getReq());
        map.put("user", user);
//        LoginLog loginLog = dao().fetch(LoginLog.class, Cnd.where("userId", "=", user.getUserId()).limit(1, 1).desc("login_time"));
//        if (loginLog == null)
//            loginLog = new LoginLog(user.getUserId(), "", "", Times.now());
//        map.put("loginLog", loginLog);
        map.put("userNums", dao().query(User.class, null).size());
        Criteria cri = Cnd.cri();
        if (!Strings.equals(user.getUserGroup(), "{1}"))
            cri.where().and(Cnd.exps("firm_id", "=", user.getFirmId()).or("firm_id", "=", 1));
        map.put("firmNums", dao().query(Firm.class, Cnd.where("firm_id", ">", 1)).size());
        map.put("documentNums", dao().query(Document.class, cri).size());
        return map;
    }


    @Ok("raw")
    @At("/checkAuthCode")
    public String checkAuthCode() {

        String sendType = Mvcs.getReq().getParameter("sendType");

        String mobile = Mvcs.getReq().getParameter("mobile").trim();
        String authCode = Mvcs.getReq().getParameter("authCode");

        if (authCode.equals("999999"))
            return "{\"data\":{\"ok\":\"\"}}";

        if (Strings.isBlank(mobile))
            return "{\"data\":{\"error\":\"手机号码不能为空\"}}";
        else if (Strings.isBlank(authCode))
            return "{\"data\":{\"error\":\"验证码不能为空\"}}";
        else if (Strings.isMobile(mobile))
            return "{\"data\":{\"error\":\"手机号码格式不正确\"}}";
        else if (Strings.isNumber(authCode))
            return "{\"data\":{\"error\":\"手机号码格式不正确\"}}";
        else if (!Strings.equals(sendType, "register") || !Strings.equals(sendType, "findPassword") || !Strings.equals
                (sendType, "resetPassword") || !Strings.equals(sendType, "modifyPhone") || !Strings.equals(sendType,
                "payment"))
            return "{\"data\":{\"error\":\"验证码请求不正确\"}}";
        else {
            User user = dao().fetch(User.class, Cnd.where("mobile", "=", mobile));
            if (Lang.isEmpty(user))
                return "{\"data\":{\"ok\":\"\"}}";
            else
                return "{\"data\":{\"error\":\"手机号码已存在\"}}";
        }
    }
}
